package com.imooc.common.thread;


import cn.hutool.core.thread.ThreadUtil;
import cn.hutool.json.JSONUtil;
import com.google.common.util.concurrent.ThreadFactoryBuilder;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.*;

public class FutureTaskTest {

    public static void main(String[] args) {
        ThreadFactory threadFactory = new ThreadFactoryBuilder()
                .setNameFormat("myThread-%d").build();

        ExecutorService pool = new ThreadPoolExecutor(
                5,
                200,
                0L,
                TimeUnit.MILLISECONDS,
                new LinkedBlockingQueue<>(1024),
                threadFactory,
                new ThreadPoolExecutor.AbortPolicy());

        Callable callable1 = ()->{
            System.out.println("callable1 start");
            ThreadUtil.sleep(10000);
            System.out.println("callable1 end");

            return "callable1";
        };
        Callable callable2 = ()->{
            System.out.println("callable2 start");
            ThreadUtil.sleep(5000);
            System.out.println("callable2 end");
            return "callable2";
        };
        Callable callable3 = ()->{
            System.out.println("callable3 start");
            ThreadUtil.sleep(3000);
            System.out.println("callable3 end");
            return "callable3";
        };

        long startTime = System.currentTimeMillis();
        List<Future<String>> tasks = new ArrayList<>();

        Future<String> task1 =  pool.submit(callable1);
        Future<String> task2 =  pool.submit(callable2);
        Future<String> task3 =  pool.submit(callable3);

        tasks.add(task1);
        tasks.add(task2);
        tasks.add(task3);

        List<String> results = new ArrayList<>();

        while(true){
            if (results.size()==1){
                pool.shutdownNow();
                break;

            }
            long currentTime = System.currentTimeMillis();
            long dimTime = currentTime-startTime;
            if (dimTime<=6000&&results.size()<tasks.size()){
                for (Future<String> task : tasks) {
                    if (finished(task)){ // 任务没有被取消而且是正常执行结束的状态
                        try {
                            if (!results.contains(task.get())){
                                System.out.println("获取到数据了!");
                                results.add(task.get());
                            }
                        }catch (InterruptedException e){
                            System.out.println("守护线程阻塞被打断");
                            Thread.currentThread().interrupt();
                        }catch (ExecutionException e){
                            System.out.println("执行任务出错");
                        }

                    }
                }

            }else{
                for (Future<String> task : tasks) {
                    if (!task.isDone()){
                        /** 调用了Thread的interrupt方法，而interrupt只能是停掉线程中有sleep,wait,join逻辑的线程，抛出一个InterruptException **/
                        task.cancel(true);
                        System.out.println(" 任务已取消");
                        System.out.println("isDone? "+task.isDone());
                    }
                }
                break;
            }

        }
        System.out.println(JSONUtil.toJsonStr(results));
        pool.shutdown();
    }

    private static boolean finished(Future<String> task) {
        return task.isDone() && !task.isCancelled();
    }


}
